home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / OWLINC.PAK / OLEFACTO.H < prev    next >
C/C++ Source or Header  |  1997-05-06  |  11KB  |  383 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1994, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.4  $
  6. //
  7. // Templatized class implementation of OLE component creation code for
  8. // TComponentFactory callback for ObjectWindows applications
  9. // All templates assume an AppDictionary global and a Registrar global
  10. // User can provide alternate implementation for any or all of the functions
  11. // The user's derived TApplication class is passed as the template parameter
  12. //
  13. //----------------------------------------------------------------------------
  14. #if !defined(OWL_OLEFACTO_H)
  15. #define OWL_OLEFACTO_H
  16.  
  17. #if !defined(OWL_DEFS_H)
  18. # include <owl/defs.h>
  19. #endif
  20. #if !defined(OCF_OLEUTIL_H)
  21. # include <ocf/oleutil.h>
  22. #endif
  23. #if !defined(OCF_OCREG_H)
  24. # include <ocf/ocreg.h>
  25. #endif
  26. #if !defined(OWL_OLEWINDO_H)
  27. # include <owl/olewindo.h>
  28. #endif
  29. #if defined(BI_NAMESPACE)
  30. namespace OWL {
  31. #endif
  32.  
  33. // Generic definitions/compiler options (eg. alignment) preceeding the
  34. // definition of classes
  35. #include <services/preclass.h>
  36.  
  37. //----------------------------------------------------------------------------
  38. // Non-automated application automation callout stub implementation
  39. //
  40.  
  41. template <class T> struct TOleFactoryNoAuto {
  42.   static void      AutomateApp(T* app, uint32 options);
  43.   static TUnknown* AutomateObject(T* app, const void* obj,const typeinfo& info);
  44.   static void      UnregisterAutomation(T* app);
  45. };
  46.  
  47. //
  48. template<class T> void
  49. TOleFactoryNoAuto<T>::AutomateApp(T* /*app*/, uint32) {
  50.  
  51. }
  52.  
  53. //
  54. template<class T> TUnknown*
  55. TOleFactoryNoAuto<T>::AutomateObject(T*, const void*,const typeinfo&) {
  56.   return 0;
  57. }
  58.  
  59. //
  60. template<class T> void
  61. TOleFactoryNoAuto<T>::UnregisterAutomation(T* /*app*/) {
  62.  
  63. }
  64.  
  65. //----------------------------------------------------------------------------
  66. // Automated application default automation callout implementation
  67. //
  68.  
  69. template <class T> struct TOleFactoryAuto {
  70.   static void      AutomateApp(T* app, uint32 options);
  71.   static TUnknown* AutomateObject(T* app, const void* obj,const typeinfo& info);
  72.   static void      UnregisterAutomation(T* app);
  73. };
  74.  
  75. //
  76. // Default callout to aggregate an automation helper to an automated object
  77. //
  78. template <class T> TUnknown*
  79. TOleFactoryAuto<T>::AutomateObject(T* app,const void* obj,const typeinfo& info)
  80. {
  81.   return ::Registrar->CreateAutoObject(obj, info, app, typeid(*app));
  82. }
  83.  
  84. //
  85. // Default callout to unregister automation active object
  86. //
  87. template <class T> void
  88. TOleFactoryAuto<T>::UnregisterAutomation(T* app)
  89. {
  90.   ::Registrar->ReleaseAutoApp(TAutoObject<T>(app));
  91. }
  92.  
  93. //
  94. // Default callout to aggregate an automation helper to an automated app
  95. //
  96. template <class T> void
  97. TOleFactoryAuto<T>::AutomateApp(T* app, uint32 options)
  98. {
  99.   ::Registrar->CreateAutoApp(TAutoObjectDelete<T>(app), options);
  100. }
  101.  
  102. //----------------------------------------------------------------------------
  103. // Application creation/destruction callouts shared for doc/view and non-d/v
  104. //
  105.  
  106. template<class T, class Auto> struct TOleFactoryAppBase {
  107.   static T*        CreateApp(uint32 options);
  108.   static void      DestroyApp(T* app);
  109. };
  110.  
  111. //
  112. template<class T, class Auto> T*
  113. TOleFactoryAppBase<T, Auto>::CreateApp(uint32 options)
  114. {
  115.   T* app = new T;
  116.   if ((options & amEmbedding) || !(options & amExeMode))
  117.     app->nCmdShow = SW_HIDE;
  118.   app->OcInit(*::Registrar, options);
  119.   Auto::AutomateApp(app, options);
  120.   app->Start();
  121.   return app;
  122. }
  123.  
  124. //
  125. template<class T, class Auto>
  126. void TOleFactoryAppBase<T, Auto>::DestroyApp(T* app)
  127. {
  128.   Auto::UnregisterAutomation(app);
  129.   delete app;
  130. }
  131.  
  132. //----------------------------------------------------------------------------
  133. // Non-docview application callout implementation, no CreateObject implemented
  134. // User must either provide an implementation of CreateOleObject for app class
  135. // or else reimplement this template function for the particular class
  136. //
  137.  
  138. template<class T, class Auto> struct TOleFactoryNoDocView
  139.                                    : TOleFactoryAppBase<T, Auto> {
  140.   static TUnknown* CreateObject(T* app, uint32 options, TRegLink* link);
  141. };
  142.  
  143. //
  144. template <class T, class Auto> TUnknown*
  145. TOleFactoryNoDocView<T, Auto>::CreateObject(T* app, uint32 options,
  146.                                             TRegLink* link)
  147. {
  148.   return app->CreateOleObject(options, link);
  149. }
  150.  
  151. //----------------------------------------------------------------------------
  152. // Docview application callout implementation - supplies CreateObject function
  153. //
  154.  
  155. template <class T, class Auto> struct TOleFactoryDocView
  156.                                     : TOleFactoryAppBase<T, Auto> {
  157.   static TUnknown* CreateObject(T* app, uint32 options, TRegLink* link);
  158. };
  159.  
  160. //
  161. template <class T, class Auto> TUnknown*
  162. TOleFactoryDocView<T, Auto>::CreateObject(T* app, uint32 options, TRegLink* link)
  163. {
  164.   TUnknown* obj = 0;
  165.   if (!link)      // if not coming up embedded, we don't know what to make here
  166.     return 0;
  167.   TDocManager* docMan = app->GetDocManager();
  168.   if (!docMan)
  169.     return 0;
  170.   TDocTemplate* tpl = static_cast<TDocTemplate*>(link);
  171.   TDocument* doc = docMan->CreateDoc(tpl, 0, 0, dtNewDoc | dtNoAutoView);
  172.   TView* view = tpl->ConstructView(*doc);
  173.   TOleWindow* ow = TYPESAFE_DOWNCAST(view, TOleWindow);
  174.   if (ow) {
  175.     obj = ow->CreateOcView(tpl, (options & amEmbedding) != 0, 0);
  176.     TUnknown* autoObj;
  177.     void* viewObj = dynamic_cast<void*>(view); // get address of derived most
  178.     void* docObj = dynamic_cast<void*>(doc);
  179.     if ((autoObj = Auto::AutomateObject(app, viewObj, typeid(*view))) != 0 ||
  180.         (autoObj = Auto::AutomateObject(app, docObj,  typeid(*doc)))  != 0) {
  181.       obj->SetOuter(&autoObj->Aggregate(*obj));
  182.       obj->AdjustRefCount(-1);  // remove extra ref count
  183.       obj = autoObj;
  184.       obj->AdjustRefCount(+1);  // add it back to the new outer sub-object
  185.     }
  186.   }
  187.   doc->InitView(view);
  188.   return (options & amEmbedding) ? obj : 0;
  189. }
  190.  
  191. //----------------------------------------------------------------------------
  192. // Standard factory for OWL components, callouts supplied via template args
  193. //
  194. template <class T, class Obj> class TOleFactoryBase {
  195.   public:
  196.     operator TComponentFactory() {return Create;}
  197.     static IUnknown* Create(IUnknown* outer, uint32 options, uint32 id);
  198. };
  199.  
  200. /*
  201. //
  202. template <class T, class Obj>
  203. TOleFactoryBase<T, Obj>::operator TComponentFactory()
  204. {
  205.   return Create;
  206. }
  207. */
  208.  
  209. //
  210. // Main Create callback function called to create app and/or object
  211. //
  212. template <class T, class Obj> IUnknown*
  213. TOleFactoryBase<T, Obj>::Create(IUnknown* outer, uint32 options, uint32 id)
  214. {
  215.   TRegLink* link = reinterpret_cast<TRegLink*>(id);
  216.  
  217.   // Look for the app object for this process, creating one if necessary
  218.   //
  219.   TApplication* existingApp = ::AppDictionary.GetApplication();
  220.   T* app;
  221.   if (!existingApp) {
  222.     if (options & amShutdown)   // app already destructed
  223.       return 0;
  224.     app = Obj::CreateApp(options);
  225.     if (!link && !(options & amEmbedding)) {
  226.       Obj::CreateObject(app, options, link);
  227.     }
  228.   } else {
  229.     app = TYPESAFE_DOWNCAST(existingApp, T);
  230.     if (options & amShutdown) {
  231.       Obj::DestroyApp(app);
  232.       return 0;  // any interface present when passed in has now been released
  233.     }
  234.   }
  235.   TUnknown* obj = app->OcApp;   // app's COM interface, used if not doc object
  236.  
  237.   // If a component ID was passed, make that component, otherwise return app
  238.   //
  239.   if (link) {
  240.     TUnknown* doc = Obj::CreateObject(app, options, link);
  241.     if (doc)
  242.       obj = doc;
  243.     else if (!(options & amEmbedding))  // run DLL in ExeMode from doc factory
  244.       app->OcApp->SetOption(amServedApp, true);
  245.     else
  246.       return 0;  // doc factory failed
  247.   }
  248.   IUnknown* ifc = obj ? obj->SetOuter(outer) : 0; // aggregate to passed outer
  249.  
  250.   // Run message look if ExeMode, either EXE server or DLL server force to run
  251.   // EXE servers come through here twice, no Run if 2nd pass from factory call
  252.   //
  253.   if (options & amRun)
  254.     app->Run();
  255.  
  256.   return ifc;
  257. }
  258.  
  259. //----------------------------------------------------------------------------
  260. //  Factory for OWL non-Doc/View, non-automated OLE components
  261. //
  262. template <class T> class TOleFactory
  263. : public TOleFactoryBase<T, TOleFactoryNoDocView<T, TOleFactoryNoAuto<T> > >
  264. {
  265. };
  266.  
  267. //
  268. //  Factory for OWL Doc/View, non-automated OLE components
  269. //
  270. template <class T> class TOleDocViewFactory
  271. : public TOleFactoryBase<T, TOleFactoryDocView<T, TOleFactoryNoAuto<T> > >
  272. {
  273. };
  274.  
  275. //
  276. //  Factory for OWL non-Doc/View, automated OLE components
  277. //
  278. template <class T> class TOleAutoFactory
  279. : public TOleFactoryBase<T, TOleFactoryNoDocView<T, TOleFactoryAuto<T> > >
  280. {
  281. };
  282.  
  283. //
  284. //  Factory for OWL Doc/View, automated OLE components
  285. //
  286. template <class T> class TOleDocViewAutoFactory
  287. : public TOleFactoryBase<T, TOleFactoryDocView<T, TOleFactoryAuto<T> > >
  288. {
  289. };
  290.  
  291. //----------------------------------------------------------------------------
  292. //  Factory for OWL automated OLE components, no linking/embedding support
  293. //
  294.  
  295. template <class T> class TAutoFactory {
  296.   public:
  297.     operator TComponentFactory() {return Create;}
  298.  
  299.     // Callouts to allow replacement of individual creation steps
  300.     //
  301.     static T*        CreateApp(uint32 options);
  302.     static void      DestroyApp(T* app);
  303.  
  304.     // Main Create callback function called to create app and/or object
  305.     //
  306.     static IUnknown* Create(IUnknown* outer, uint32 options, uint32 id);
  307. };
  308.  
  309. /*
  310. //
  311. template <class T>
  312. TAutoFactory<T>::operator TComponentFactory()
  313. {
  314.   return Create;
  315. }
  316. */
  317.  
  318. //
  319. // Called when the app is not found and needs to be created
  320. //
  321. template <class T> T*
  322. TAutoFactory<T>::CreateApp(uint32 options)
  323. {
  324.   T* app = new T;
  325.   if ((options & amEmbedding) || !(options & amExeMode))
  326.     app->nCmdShow = SW_HIDE;
  327.   app->Start();
  328.   return app;
  329. }
  330.  
  331. //
  332. // Called to destroy the application previously created
  333. //
  334. template <class T> void
  335. TAutoFactory<T>::DestroyApp(T* app)
  336. {
  337.   delete app;
  338. }
  339.  
  340. //
  341. // Main Create callback function called to create app
  342. //
  343. template <class T> IUnknown*
  344. TAutoFactory<T>::Create(IUnknown* outer, uint32 options, uint32 /*id*/)
  345. {
  346.   IUnknown* ifc = 0;
  347.   TApplication* existingApp = ::AppDictionary.GetApplication();
  348.   T* app;
  349.   if (!existingApp) {
  350.     if (options & amShutdown)   // app already destructed
  351.       return 0;
  352.     app = CreateApp(options);
  353.   }
  354.   else {
  355.     app = TYPESAFE_DOWNCAST(existingApp, T);
  356.     if (options & amShutdown) {
  357.       DestroyApp(app);
  358.       return (options & amServedApp) ? 0 : outer;
  359.     }
  360.   }
  361.  
  362.   if (options & amServedApp) {
  363.     TUnknown* obj = ::Registrar->CreateAutoApp(TAutoObjectDelete<T>(app),
  364.                                                options, outer);
  365.     ifc = *obj;  // does an AddRef, reference count owned by container
  366.   }
  367.  
  368.   if (options & amRun) {
  369.     app->Run();
  370.   }
  371.   return ifc;
  372. }
  373.  
  374. // Generic definitions/compiler options (eg. alignment) following the
  375. // definition of classes
  376. #include <services/posclass.h>
  377.  
  378. #if defined(BI_NAMESPACE)
  379. } // namespace OWL
  380. #endif
  381.  
  382. #endif  // OWL_OLEFACTO_H
  383.